﻿using CoreModule;
using Prism.Regions;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.Tracing;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using Windows.Devices.Bluetooth;
using Windows.Devices.Bluetooth.Advertisement;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Enumeration;
using Windows.Foundation;
using Windows.Security.Cryptography;

namespace UIModule.Views
{
    /// <summary>
    /// BluetoothPicker.xaml 的交互逻辑
    /// </summary>
    public partial class BluetoothDataPicker : Window, INotifyPropertyChanged
    {

        /// <summary>
        /// 根服务 00001808-0000-1000-8000-00805f9b34fb
        /// </summary>
        public Guid GlucoseServiceUuid = Guid.Parse("00001808-0000-1000-8000-00805F9B34FB");

        /// <summary>
        /// 数据回传通道
        /// </summary>
        public Guid GlucoseMeasurementUuid = Guid.Parse("00002A18-0000-1000-8000-00805F9B34FB");

        /// <summary>
        /// 数据的测量模式
        /// </summary>
        public Guid ClucoseMeasurementContextUuid = Guid.Parse("00002A34-0000-1000-8000-00805F9B34FB");

        /// <summary>
        /// 控制通道
        /// </summary>
        public Guid GlucoseRecordAccessControlPointUuid = Guid.Parse("00002A52-0000-1000-8000-00805F9B34FB");

        /// <summary>
        /// 正在连接中。。。
        /// </summary>
        public int ConnectingSeconds { get; set; } = 0;

        /// <summary>
        /// 设备列表
        /// </summary>
        public List<BluetoothInformation> BluetoothInformationList { get; set; } = new List<BluetoothInformation>();
        /// <summary>
        /// 
        /// </summary>
        public List<string> DeviceAddressList { get; set; } = new List<string>();

        /// <summary>
        /// 
        /// </summary>
        IRegionManager RegionManager { get; set; }

        /// <summary>
        /// 
        /// </summary>
        IWindowLifetime WindowLifetime { get; set; }

        /// <summary>
        /// 
        /// </summary>
        PickerGridKind PickerGridKind { get; set; }



        /// <summary>
        /// 
        /// </summary>
        /// <param name="regionManager"></param>
        public BluetoothDataPicker(IRegionManager regionManager, IWindowLifetime windowLifetime)
        {
            InitializeComponent();
            RegionManager = regionManager;
            WindowLifetime = windowLifetime;

            this.PickerGridKind = PickerGridKind.GridConnectionPrompt;

            ShowGridConnectionPrompt();

            LastDataDispatcherTimer = new DispatcherTimer(DispatcherPriority.Background);

            LastDataDispatcherTimer.Interval = TimeSpan.FromSeconds(Extension.GetBluetoothDataTimeoutSeconds());

            LastDataDispatcherTimer.Tick += LastDataDispatcherTimer_Tick;
            LastDataDispatcherTimer.Start();
        }
        /// <summary>
        /// 显示连接提示
        /// </summary>

        private void ShowGridConnectionPrompt()
        {

            this.Dispatcher.Invoke(() => {
            this.gridConnectionPrompt.Visibility = Visibility.Visible;
            this.gridConnecting.Visibility = Visibility.Collapsed;
            this.gridSelectTheDeviceYouWanToConnectTo.Visibility = Visibility.Collapsed;
            this.gridSyncingData.Visibility = Visibility.Collapsed;
            });
        }

        /// <summary>
        /// 显示连接中
        /// </summary>
        private void ShowConnecting()
        {
            this.Dispatcher.Invoke(() =>
            {

                this.gridConnectionPrompt.Visibility = Visibility.Collapsed;
                this.gridConnecting.Visibility = Visibility.Visible;
                this.gridSelectTheDeviceYouWanToConnectTo.Visibility = Visibility.Collapsed;
                this.gridSyncingData.Visibility = Visibility.Collapsed;
            });
        }
        /// <summary>
        /// 显示设备
        /// </summary>
        private void ShowSelectTheDeviceYouWanToConnectTo()
        {
            this.Dispatcher.Invoke(() =>
            {
                this.gridConnectionPrompt.Visibility = Visibility.Collapsed;
                this.gridConnecting.Visibility = Visibility.Collapsed;
                this.gridSelectTheDeviceYouWanToConnectTo.Visibility = Visibility.Visible;
                this.gridSyncingData.Visibility = Visibility.Collapsed;

                this.lsBluetooth.ItemsSource = new List<BluetoothInformation>();
                this.BluetoothInformationList = this.BluetoothInformationList.Distinct(new BluetoothInformationEqualityComparer()).ToList();
                this.lsBluetooth.ItemsSource = this.BluetoothInformationList;
                if (this.BluetoothInformationList.Count == 0)
                {
                    this.spNoHasDevice.Visibility = Visibility.Visible;
                    this.lsBluetooth.Visibility = Visibility.Collapsed;
                }
                else
                {
                    this.spNoHasDevice.Visibility = Visibility.Collapsed;
                    this.lsBluetooth.Visibility = Visibility.Visible;

                }
            });
        }
        /// <summary>
        /// 显示 同步数据
        /// </summary>
        private void ShowSyncingData()
        {
            this.Dispatcher.Invoke(() =>
            {
                this.gridConnectionPrompt.Visibility = Visibility.Collapsed;
                this.gridConnecting.Visibility = Visibility.Collapsed;
                this.gridSelectTheDeviceYouWanToConnectTo.Visibility = Visibility.Collapsed;
                this.gridSyncingData.Visibility = Visibility.Visible;
            });
        }

        /// <summary>
        /// 
        /// </summary>
        public void ReScanningBluetoothSignal()
        {
            this.YuWellBloodGlucoseDeviceNameList.Clear();
            this.NotYuWellBloodGlucoseBluetoothAddressList.Clear();
            this.BluetoothInformationList.Clear();

            if(Watcher!=null)
            {
                Watcher.Stop();
            }


            Watcher = new BluetoothLEAdvertisementWatcher();

            Watcher.ScanningMode = BluetoothLEScanningMode.Active;

            // only activate the watcher when we're recieving values >= -80
            Watcher.SignalStrengthFilter.InRangeThresholdInDBm = -80;

            // stop watching if the value drops below -90 (user walked away)
            Watcher.SignalStrengthFilter.OutOfRangeThresholdInDBm = -90;

            // register callback for when we see an advertisements
            Watcher.Received += Watcher_Received;
             
            // wait 5 seconds to make sure the device is really out of range
            Watcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(15000);
            Watcher.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(2000);

            // starting watching for advertisements
            Watcher.Start();
        }

        private void Watcher_Stopped(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementWatcherStoppedEventArgs args)
        {
            
        }

        /// <summary>
        /// 设备 查找
        /// </summary>

        private BluetoothLEAdvertisementWatcher Watcher = null;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.DataContext = this;

            this.PickerGridKind = PickerGridKind.GridSelectTheDeviceYouWanToConnectTo;

            this.spNoHasDevice.Visibility = Visibility.Visible;
            this.lsBluetooth.Visibility = Visibility.Collapsed;
            
            ReScanningBluetoothSignal();

        }
        /// <summary>
        /// 
        /// </summary>
      


        public  string ConvertBluetoothAddressToMac(ulong bluetoothAddress)
        {
            byte[] addressBytes = BitConverter.GetBytes(bluetoothAddress);
            Array.Reverse(addressBytes); // 大端到小端转换

            string macAddress = BitConverter.ToString(addressBytes, 2, 6)
                .Replace("-", "")
                .ToUpper();
            return macAddress;
             

        }

        /// <summary>
        /// 
        /// </summary>

        public List<ulong> NotYuWellBloodGlucoseBluetoothAddressList = new List<ulong>();


        public List<string> YuWellBloodGlucoseDeviceNameList { get; private set; } = new List<string>();

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void Watcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
        {

            //// 已经 认为不是Yuwell 产品
            if (NotYuWellBloodGlucoseBluetoothAddressList.Contains(eventArgs.BluetoothAddress))
            {
                return;
            }

            var bluetoothAddress = eventArgs.BluetoothAddress;

            var bluetoothInformation = this.BluetoothInformationList.FirstOrDefault(item => item.BluetoothAddress == bluetoothAddress);

            ///说明已经存在了,更新
            if (bluetoothInformation != null)
            {
                bluetoothInformation.Timestamp = eventArgs.Timestamp;

                return;
            }

            BluetoothLEDevice.FromBluetoothAddressAsync(eventArgs.BluetoothAddress).Completed = (asyncInfo, asyncStatus) =>
            {
                if (asyncStatus == AsyncStatus.Completed)
                {
                    if (asyncInfo.GetResults() == null)
                    {
                      //  this.BluetoothInformationList.RemoveAll(item=>item.BluetoothAddress == bluetoothAddress);

                        //this.Dispatcher.Invoke(new Action(() => {

                        //    if (this.PickerGridKind == PickerGridKind.GridSelectTheDeviceYouWanToConnectTo)
                        //    {
                        //        this.ShowSelectTheDeviceYouWanToConnectTo();
                        //    }

                        //    this.RaisePropertyChanged(nameof(this.BluetoothInformationList));

                        //    this.lsBluetooth.ItemsSource = new List<BluetoothInformation>();
                        //    this.lsBluetooth.ItemsSource = this.BluetoothInformationList;

                        //}));
                    }
                    else
                    {

                        var deviceAddress = ConvertBluetoothAddressToMac(bluetoothAddress);

                        BluetoothLEDevice currentDevice = asyncInfo.GetResults();

                        var deviceName = currentDevice.Name + " " + deviceAddress;

                        if (!deviceName.ToLower().Contains("glucose"))
                        {

                            ///不是 yuwell 的
                            if (!this.NotYuWellBloodGlucoseBluetoothAddressList.Contains(bluetoothAddress))
                            {
                                this.NotYuWellBloodGlucoseBluetoothAddressList.Add(bluetoothAddress);
                            }

                            currentDevice.Dispose();
                            return;
                        }

                        YuWellBloodGlucoseDeviceNameList.Add(deviceName);

                        ///加入
                        this.BluetoothInformationList.Add(new BluetoothInformation()
                        {
                            Name = currentDevice.Name,
                            Timestamp = eventArgs.Timestamp,
                            DeviceAddress = deviceAddress,
                            DeviceId = currentDevice.DeviceId,
                            DeviceName = deviceName,
                             BluetoothAddress=eventArgs.BluetoothAddress,
                        });
                            this.Dispatcher.Invoke(new Action(() => {

                                if (this.PickerGridKind == PickerGridKind.GridSelectTheDeviceYouWanToConnectTo)
                                {
                                    this.ShowSelectTheDeviceYouWanToConnectTo();
                                }

                                this.RaisePropertyChanged(nameof(this.BluetoothInformationList));

                                this.lsBluetooth.ItemsSource = new List<BluetoothInformation>();
                                this.lsBluetooth.ItemsSource = this.BluetoothInformationList;

                                if (this.BluetoothInformationList.Count == 0)
                                {
                                    this.spNoHasDevice.Visibility = Visibility.Visible;
                                    this.lsBluetooth.Visibility = Visibility.Collapsed;
                                }
                                else
                                {
                                    this.spNoHasDevice.Visibility = Visibility.Collapsed;
                                    this.lsBluetooth.Visibility = Visibility.Visible;

                                }

                            }));

                        
                        currentDevice.Dispose();

                    }

                }
            };
        }

       
      
        /// <summary>
        /// 
        /// </summary>
        public DispatcherTimer ConnectingDispatcherTimer { get; set; } = new DispatcherTimer();

        /// <summary>
        /// 
        /// </summary>
        public BluetoothLEDevice ConnectingBluetoothLEDevice { get; set; }

        /// <summary>
        /// 血糖
        /// </summary>

        GattDeviceService GattDeviceService { get; set; }

        /// <summary>
        /// 血糖测量
        /// </summary>
        GattCharacteristic GlucoseMeasurementCharacteristic { get; set; }

        /// <summary>
        /// 数据的测量模式
        /// </summary>
       // GattCharacteristic ClucoseMeasurementContextCharacteristic { get; set; }

        /// <summary>
        /// 记录读取控制点
        /// </summary>
        GattCharacteristic RecordAccessControlPointCharacteristic { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public async Task ProcessAsync(BluetoothLEDevice bluetoothLEDevice)
        {

            try
            {

                 GattDeviceServicesResult servicesResult = await bluetoothLEDevice.GetGattServicesForUuidAsync(GlucoseServiceUuid, BluetoothCacheMode.Uncached);

                if (servicesResult.Status != GattCommunicationStatus.Success)
                {
                    this.ShowGridConnectionPrompt();
                    return;
                }

                GattDeviceService = servicesResult.Services.FirstOrDefault();
                if (GattDeviceService == null)
                {
                    this.ShowGridConnectionPrompt();
                    return;
                }
              

                var glucoseMeasurementResult = await GattDeviceService.GetCharacteristicsForUuidAsync(GlucoseMeasurementUuid);

                if (glucoseMeasurementResult.Status != GattCommunicationStatus.Success)
                {
                    GattDeviceService.Dispose();
                    this.ShowGridConnectionPrompt();
                    return;
                }

                GlucoseMeasurementCharacteristic = glucoseMeasurementResult.Characteristics.FirstOrDefault();
                if (GlucoseMeasurementCharacteristic == null)
                {
                    GattDeviceService.Dispose();
                    this.ShowGridConnectionPrompt();
                    return;
                }

                 
                var recordAccessControlPointCharacteristicsResult = await GattDeviceService.GetCharacteristicsForUuidAsync(GlucoseRecordAccessControlPointUuid);

                if (recordAccessControlPointCharacteristicsResult.Status != GattCommunicationStatus.Success)
                {
                    GattDeviceService.Dispose();
                    this.ShowGridConnectionPrompt();
                    return;
                }

                 RecordAccessControlPointCharacteristic = recordAccessControlPointCharacteristicsResult.Characteristics.FirstOrDefault();
                if (RecordAccessControlPointCharacteristic == null)
                {
                    GattDeviceService.Dispose();
                    this.ShowGridConnectionPrompt();
                    return;
                }

                try
                {

                    LastDataDateTime = DateTime.Now;
                    this.PickerGridKind = PickerGridKind.GridSyncingData;

                    GlucoseMeasurementCharacteristic.ValueChanged += GlucoseMeasurementCharacteristic_ValueChanged;
                    ///打开
                  var kks=  await GlucoseMeasurementCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);
                     
                    Windows.Storage.Streams.IBuffer buffer = CryptographicBuffer.CreateFromByteArray(new byte[] { 1, 1 });

                  var jjs=  await RecordAccessControlPointCharacteristic.WriteValueAsync(buffer);

                    this.ShowSyncingData();

                }
                catch (Exception)
                {
                    GlucoseMeasurementCharacteristic.ValueChanged -= GlucoseMeasurementCharacteristic_ValueChanged;

                }
            } catch (Exception )
            {

            }

         }

        int TimeoutIndex =0;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LastDataDispatcherTimer_Tick(object sender, EventArgs e)
        {

            TimeoutIndex = (TimeoutIndex + 1) % 4;

            if (TimeoutIndex == 0)
            {
                var timeoutItems = this.BluetoothInformationList
                    .Where(item => DateTime.Now.Subtract(item.Timestamp.DateTime).TotalSeconds > 20)
                   .ToList();

                foreach (var item in timeoutItems)
                {
                    this.YuWellBloodGlucoseDeviceNameList.Remove(item.DeviceName);
                }

                this.Dispatcher.Invoke(new Action(() =>
                {

                    this.BluetoothInformationList= this.BluetoothInformationList
                    .Where(item => DateTime.Now.Subtract(item.Timestamp.DateTime).TotalSeconds < 20)
                    .ToList();

                    this.RaisePropertyChanged(nameof(this.BluetoothInformationList));

                   this.lsBluetooth.ItemsSource = new List<BluetoothInformation>();
                   this.lsBluetooth.ItemsSource = this.BluetoothInformationList;
                    if (this.BluetoothInformationList.Count == 0)
                    {
                        this.spNoHasDevice.Visibility = Visibility.Visible;
                        this.lsBluetooth.Visibility = Visibility.Collapsed;
                    }
                    else
                    {
                        this.spNoHasDevice.Visibility = Visibility.Collapsed;
                        this.lsBluetooth.Visibility = Visibility.Visible;

                    }

                }));
            }


            if (DateTime.Now.Subtract(LastDataDateTime).TotalSeconds > 5
                && this.PickerGridKind== PickerGridKind.GridSyncingData)
            {
                this.IsClosing = true;
                this.Dispatcher.Invoke(new Action(() =>
                {
                    this.Close();
                }));
            }
        }
          
     
        /// <summary>
        /// 
        /// </summary>
        List<string> values = new List<string>();

        /// <summary>
        /// 
        /// </summary>
        public List<BloodGlucoseMeasurementInfo> BloodGlucoseMeasurementInfos { get; set; } = new List<BloodGlucoseMeasurementInfo>();


        /// <summary>
        /// 
        /// </summary>
        public DispatcherTimer LastDataDispatcherTimer { get; set; } 

        /// <summary>
        /// 
        /// </summary>

        public DateTime LastDataDateTime { get; set; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void GlucoseMeasurementCharacteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
        {

            LastDataDateTime = DateTime.Now;

            byte[] bytes;
            CryptographicBuffer.CopyToByteArray(args.CharacteristicValue, out bytes);
             
            var glucoseMeasurementInfo = CoreModule.BloodGlucoseMeasurementInfo.Create(bytes);

            if (glucoseMeasurementInfo.IsValid)
            {
                BloodGlucoseMeasurementInfos.Add(glucoseMeasurementInfo);
                this.EntityTotalCount = BloodGlucoseMeasurementInfos.Count;
            }
            this.Dispatcher.Invoke(() =>
            {
                this.RaisePropertyChanged(nameof(this.EntityTotalCount));
            });

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="bluetoothInformation"></param>
        public  void StartConnecte(BluetoothInformation bluetoothInformation)
        { 

              BluetoothLEDevice.FromIdAsync(bluetoothInformation.DeviceId)
                .Completed = async (asyncInfo, asyncStatus) =>
                {
                    if (asyncStatus == AsyncStatus.Completed)
                    {
                        ConnectingBluetoothLEDevice = asyncInfo.GetResults();

                        if (ConnectingBluetoothLEDevice == null)
                        {
                            this.Dispatcher.Invoke(() =>
                            {
                                this.ShowSelectTheDeviceYouWanToConnectTo();
                            });
                            return;
                        } 


                        else
                        {

                               var connectionStatus = ConnectingBluetoothLEDevice.ConnectionStatus;

                           
                                this.ShowConnecting();
                                if (GlucoseMeasurementCharacteristic != null)
                                {
                                    GlucoseMeasurementCharacteristic.ValueChanged -= GlucoseMeasurementCharacteristic_ValueChanged;
                                }

                                if (GlucoseMeasurementCharacteristic != null)
                                {
                                    GlucoseMeasurementCharacteristic.ValueChanged += GlucoseMeasurementCharacteristic_ValueChanged;
                                }

                                this.GattDeviceService?.Dispose();

                                this.GlucoseMeasurementCharacteristic = null;
                                this.RecordAccessControlPointCharacteristic = null;

                                await ProcessAsync(ConnectingBluetoothLEDevice);
                           

                        }
                    }
                };

        } 
      

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (this.IsClosing)
            {
                return;
            }
            else
            {
                e.Cancel = true;
            }

        }

        public bool IsClosing = false;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClose_Click(object sender, RoutedEventArgs e)
        {
            IsClosing = true;
            this.Close();
        }

        BluetoothInformation? UsedBluetoothInformation { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public int EntityTotalCount { get; set; } = 0;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnConnect_Click(object sender, RoutedEventArgs e)
        {
            this.EntityTotalCount = 0;
            this.BloodGlucoseMeasurementInfos.Clear();

            this.PickerGridKind = PickerGridKind.GridConnecting;
            this.ConnectingSeconds = 0;
            this.RaisePropertyChanged(nameof(this.ConnectingSeconds));

            this.ShowConnecting();
            var bluetoothInformation = (sender as System.Windows.Controls.Control).Tag as BluetoothInformation;
            this.lblDeviceName.Text = bluetoothInformation.DeviceName;
            this.StartConnecte(bluetoothInformation);
             

        }

        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Checks if a property already matches a desired value. Sets the property and
        /// notifies listeners only when necessary.
        /// </summary>
        /// <typeparam name="T">Type of the property.</typeparam>
        /// <param name="storage">Reference to a property with both getter and setter.</param>
        /// <param name="value">Desired value for the property.</param>
        /// <param name="propertyName">Name of the property used to notify listeners. This
        /// value is optional and can be provided automatically when invoked from compilers that
        /// support CallerMemberName.</param>
        /// <returns>True if the value was changed, false if the existing value matched the
        /// desired value.</returns>
        protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(storage, value)) return false;

            storage = value;
            RaisePropertyChanged(propertyName);

            return true;
        }

        /// <summary>
        /// Checks if a property already matches a desired value. Sets the property and
        /// notifies listeners only when necessary.
        /// </summary>
        /// <typeparam name="T">Type of the property.</typeparam>
        /// <param name="storage">Reference to a property with both getter and setter.</param>
        /// <param name="value">Desired value for the property.</param>
        /// <param name="propertyName">Name of the property used to notify listeners. This
        /// value is optional and can be provided automatically when invoked from compilers that
        /// support CallerMemberName.</param>
        /// <param name="onChanged">Action that is called after the property value has been changed.</param>
        /// <returns>True if the value was changed, false if the existing value matched the
        /// desired value.</returns>
        protected virtual bool SetProperty<T>(ref T storage, T value, Action onChanged, [CallerMemberName] string propertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(storage, value)) return false;

            storage = value;
            onChanged?.Invoke();
            RaisePropertyChanged(propertyName);

            return true;
        }

        /// <summary>
        /// Raises this object's PropertyChanged event.
        /// </summary>
        /// <param name="propertyName">Name of the property used to notify listeners. This
        /// value is optional and can be provided automatically when invoked from compilers
        /// that support <see cref="CallerMemberNameAttribute"/>.</param>
        protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
        {
            OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }

        /// <summary>
        /// Raises this object's PropertyChanged event.
        /// </summary>
        /// <param name="args">The PropertyChangedEventArgs</param>
        protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
        {
            PropertyChanged?.Invoke(this, args);
        }
         
        /// <summary>
        /// 资源释放
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Unloaded(object sender, RoutedEventArgs e)
        {
            try
            {
                this.ConnectingDispatcherTimer.Stop();
                this.LastDataDispatcherTimer.Stop();
                this.Watcher.Stop();

                this.GattDeviceService?.Dispose();

                this.ConnectingBluetoothLEDevice?.Dispose();
                 
                Windows.Storage.Streams.IBuffer buffer = CryptographicBuffer.CreateFromByteArray(new byte[] { 3, 0 });
                RecordAccessControlPointCharacteristic?.WriteValueAsync(buffer);
                 
            }
            catch (Exception)
            {

            }
            finally
            {


                this.Dispatcher.Invoke(() => {

                var target = WindowLifetime.RegionViewKind == RegionViewKind.History
                    ? CoreModule.CoreConstant.HistoryView
                    : CoreModule.CoreConstant.AnalysisView;


                RegionManager.RequestNavigate(CoreConstant.MainRegion, CoreModule.CoreConstant.BlankView);

                if (this.PickerGridKind != PickerGridKind.GridSyncingData)
                {

                    var bluetoothDataPickerResult = new BluetoothDataPickerResult();

                    bluetoothDataPickerResult.BluetoothQueryResult = BluetoothQueryResult.NotDevice;
                    bluetoothDataPickerResult.BloodGlucoseMeasurementInfos = new List<BloodGlucoseMeasurementInfo>();

                    Cache.BluetoothDataPickerResult = bluetoothDataPickerResult;

                    var navigationParameters = new NavigationParameters
                    {
                        {
                            CoreConstant.BluetoothDataPickerResultKey, bluetoothDataPickerResult
                        }
                    };
                    RegionManager.RequestNavigate(CoreConstant.MainRegion, target, navigationParameters);

                    IsClosing = true;

                }
                else
                {
                    var bluetoothDataPickerResult = new BluetoothDataPickerResult();

                    bluetoothDataPickerResult.BluetoothQueryResult = BluetoothQueryResult.HasDate;
                    bluetoothDataPickerResult.BloodGlucoseMeasurementInfos = new List<BloodGlucoseMeasurementInfo>();

                    foreach (var bloodGlucoseMeasurementInfo in this.BloodGlucoseMeasurementInfos)
                    {
                    
                         bloodGlucoseMeasurementInfo.SetBloodGlucosePeriodThenComputeBloodGlucoseStatus( BloodGlucosePeriod.None, BloodGlucosePeriodSourceKind.Time);
                     }
                     

                    ///
                    this.BloodGlucoseMeasurementInfos = this.BloodGlucoseMeasurementInfos
                    .OrderByDescending(item => item.MeasurementTime)
                    .ToList();

                    bluetoothDataPickerResult.BloodGlucoseMeasurementInfos.AddRange(this.BloodGlucoseMeasurementInfos);
                         
                    Cache.BluetoothDataPickerResult = bluetoothDataPickerResult;

                    var navigationParameters = new NavigationParameters
                    {
                        {
                            CoreConstant.BluetoothDataPickerResultKey, bluetoothDataPickerResult
                        }
                    };
                    RegionManager.RequestNavigate(CoreConstant.MainRegion, target, navigationParameters);

                    IsClosing = true;

                    }
                });
            }
        }
        /// <summary>
        /// 重新连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnSearch_Click(object sender, RoutedEventArgs e)
        {

            ReScanningBluetoothSignal();

            this.ShowSelectTheDeviceYouWanToConnectTo();

        }
 
    }
}